package cn.tedu.wallet.controller;

import cn.tedu.base.response.StatusCode;
import cn.tedu.wallet.consts.TradeStatus;
import cn.tedu.wallet.dao.repository.RecordRepository;
import cn.tedu.wallet.dao.repository.WalletRepository;
import cn.tedu.wallet.pojo.param.PayParam;
import cn.tedu.wallet.pojo.po.UserTransactionRecordPO;
import cn.tedu.wallet.pojo.po.UserWalletPO;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "模拟支付")
@RestController
@RequestMapping("/wallet/alipay")
public class PayController {
    /**
     * APP ID，请在支付宝沙箱应用（https://open.alipay.com/develop/sandbox/app）中查
     * 找正确的值
     */
    private static final String APP_ID = "9021000141643200";
    /**
     * 应用私钥，请在支付宝沙箱应用（https://open.alipay.com/develop/sandbox/app）中查
     * 找正确的值
     */
    private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCMVRzf3v1xjvcc3GCKWRAsuxNV91kGKP0Z3ntJKD3zA2Wqvffn9gW4qsOssa1eV89173olPZYqdxRVmjYIpip7rDeD5tYJ6jT5fqlPa4XovBCRkXarLdzYGirVwHZsxWiPrPtabMTAJDNdmKsYdqzARKjitJZTh5yQoQPq3IwXSzlFqksOPsLTWACSpe3h3fQFGu0MqIbEEmJPqiRv2k9V3SGGy4CYz+M3rXqr6R35hBFd5mrF+Kg1n+uSmX+ufk9++2ALdVwgIzzuZ4YAyVOqfQXOxxzav2P/YCubysD9PDXXhCim5X5LKZQsCf4ZM3OXRti311v650KoYyP3XH3TAgMBAAECggEAaNheTlSH/oPV1FZCOpr4HrNWau/2L0gIcX9rlOjf/+QV3U85HLEO7T2IHEpTQR1R/scA9zngK7H0G1Cv9h5Ptz6f64hXeejl01HypUesMInxxxBrHNGTIlHKlxDIadPDnzSaRqDlDrj9N3yMuCZSQwQJOfe6KIY1T0k9aAeHEw8gr3IWLFVTVpZWpupI/YN7D0P453wadm/KeltXe9hkltWDo5zqXo4aly+sPRHiZye3QUe5m0Flfi7VXbxCDVZ1nid7NrEs2/lKnoyEAzSJxPkE/q9Rer3D8ZDSLUj4StwQC9HgWjkBlXIpwdOFErs32FpRGncwhnE0UfQgeexJYQKBgQDLzZ5h4ztdrk/18jvtP0+r7Wb8l+1j1t/5QiMrBsU7am8kZKWueSYaFtJAUPhQKxIGbJSEMrX01bsrjdVYc/6hSQ8RHApK9kB7NcwHRoa8aiuJaPs39fy3dSkpB7pgHzAJl1SHzNSD4jpf86elhU+vejt/E5E/B43LLi0duKn/dwKBgQCwRgc9Gfi1yXF1h2rxrtmxKu1jJcHML4sJR41dNo5vgM1x+GGEmctoheB1k/Bzf0xi22h409M/6hDxOYWk+NQHhzp0S8T5zCQY6NvlCXoW9gUEOzHDFj7NKw4lk4ZSP/Y9kUx84WD+WYXIuc9fd6JgpuTHQ+dcLxb9Xm+Qri6jhQKBgQDFlKJn5BQ5zjRXDHBsoWRsGcwuNlw+3qJk1Gmj3Px5jcYSUkEN1QXLZTSQhe82SYtADyQsxb0Bj/PVVbvv9QR2+I1S2QxhgDsjOBSFOSqGn6d1oAFtT12hvkQZMxTM+29m3P9maH3fHgPZ4i41mfiW9rmXiTDXGkutHyc+GTk2IQKBgHNhEwHiixHqTjKgtdaGHYXC1GlOYICXKgmj5Rr7R9YiV9deve3+gM7kulwbvorK6yPV+5cDB8ZRHk/W1+x41sgqso9GvSLIhWQsnypWvqxi0jvHxzWrzOWcZgEghA44QaRhA9DF8SfrTw9o2BzkAMwE0cDAaKLFS+YCN0JbULnFAoGBAIcSjpD/rFSsQvI30sqMgRjAHJWDIr8gVbCoRvi6jdAHlUycx2BGjDQWfhJ/p++xYsOxdAnhPuvTVFIEZ3veWUm6LteDR3B0gropinph0xMJBirl5+Uwzr2LlQBZ604jijvoFz2E4yx969xo+folpwyvnp6Jy/5KW+CyUVyrbmyI";
    /**
     * 支付宝公钥，请在支付宝沙箱应用（https://open.alipay.com/develop/sandbox/app）中
     * 查找正确的值
     */
    private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtD3cN0ZB08jdtRwNK3rEvNEbtRRJG7mRxZ0/2rzjbHFrB+x9q2Je2GwAcTtamg7VBeVCmZz2Xr8UaGxbR2N/KqiCgpu+sja+Ze9wOV34NxSMoyUmnAQI2ebIdm4I4witRDIsm57vXwz4sHVs19OItqjn6dQphhtcjiwFCrWLk0y678PlAQHvwzCo7t9cHSQ7q5zDYNsGcGC8p70zXCYTmPbr5LGsdKpb9dhUOH+SsUBGGybHVxeeHsVBcOrSHHCR6gMGrNNCbW81yS9oCx2U8UJjXwmuulsdoSlqYcoS8OTg5P2P0H4OjifAv5rKeL1rX3vR6YrgsUiv2N3M2NfayQIDAQAB";
    /**
     * 通知网址，用于处理支付宝完成支付处理后，你的应用中进行下一步处理的请求地址
     */
    private static final String NOTIFY_URL = "http://fj2wz7.natappfree.cc/wallet/alipay/notify";
    /**
     * 返回网址，用于支付宝完成支付处理后，重定向到某个位置
     */
    private static final String RETURN_URL = "http://fj2wz7.natappfree.cc/wallet/alipay/finish";
    /**
     * 【固定】支付宝网关
     */
    private static final String ALIPAY_GATEWAY = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    /**
     * 【固定】加密算法
     */
    private static final String ENCRYPTION_ALGORITHM = "RSA2";
    /**
     * 【固定】字符编码
     */
    private static final String CHARSET = "UTF-8";
    /**
     * 【固定】数据格式
     */
    private static final String DATA_FORMAT = "json";
    // 此方法用于接收客户端发起的支付请求，并响应支付表单页面到客户端
    // 网页客户端应该通过window.open直接向此处发起请求，则响应的支付表单会直接显示在window.open打开的窗口中

    @ApiOperation("支付宝沙箱支付")
    @ApiOperationSupport(order = 100)
    @GetMapping("/pay")
    public String pay(PayParam payParam, @ApiIgnore HttpServletResponse response) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(ALIPAY_GATEWAY, APP_ID, PRIVATE_KEY, DATA_FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, ENCRYPTION_ALGORITHM);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //异步接收地址，仅支持http/https，公网可访问
        request.setNotifyUrl(NOTIFY_URL);
        //同步跳转地址，仅支持http/https
        request.setReturnUrl(RETURN_URL);
        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", payParam.getOutTradeNo());
        //支付金额，最小值0.01元
        bizContent.put("total_amount", payParam.getTotalAmount());
        //订单标题，不可使用特殊符号
        bizContent.put("subject", payParam.getSubject());
        //电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        /******可选参数******/
        //bizContent.put("time_expire", "2022-08-01 22:00:00");
        //// 商品明细信息，按需传入
        //JSONArray goodsDetail = new JSONArray();
        //JSONObject goods1 = new JSONObject();
        //goods1.put("goods_id", "goodsNo1");
        //goods1.put("goods_name", "子商品1");
        //goods1.put("quantity", 1);
        //goods1.put("price", 0.01);
        //goodsDetail.add(goods1);
        //bizContent.put("goods_detail", goodsDetail);
        //// 扩展信息，按需传入
        //JSONObject extendParams = new JSONObject();
        //extendParams.put("sys_service_provider_id", "2088511833207846");
        //bizContent.put("extend_params", extendParams);
        request.setBizContent(bizContent.toString());
        AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(request);
        if (alipayTradePagePayResponse.isSuccess()) {
            System.out.println("调用成功，将在浏览器中打开支付宝【沙箱】支付页");
            return alipayTradePagePayResponse.getBody();
        } else {
            return "交易失败，调用支付宝远程接口失败，请返回订单页查看订单状态，或重新支 付！";
        }
    }

    @Autowired
    private RecordRepository recordRepository;
    @Autowired
    private WalletRepository walletRepository;
    // 接收支付宝发送的通知（支付结果）
    // 注意：必须是POST请求
    @ApiIgnore
    @PostMapping("/notify")
    public String payNotify(@ApiIgnore HttpServletRequest request) throws Throwable {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            params.put(name, request.getParameter(name));
        }
        String sign = params.get("sign");
        String content = AlipaySignature.getSignCheckContentV1(params);
        boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, ALIPAY_PUBLIC_KEY, CHARSET); // 验证签名
        // 支付宝验签
        if (checkSignature) {
        // 验签通过
            System.out.println("交易名称: " + params.get("subject"));
            System.out.println("交易状态: " + params.get("trade_status"));
            System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
            System.out.println("商户订单号: " + params.get("out_trade_no"));
            System.out.println("交易金额: " + params.get("total_amount"));
            System.out.println("买家支付宝ID: " + params.get("buyer_id"));
            System.out.println("买家付款时间: " + params.get("gmt_payment"));
            System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
        // 你应该在此处补充支付成功后续的代码，例如修改订单状态等
            Long recordId = Long.valueOf(params.get("out_trade_no"));
            UserTransactionRecordPO d = recordRepository.getRecordDetail(recordId);
            if (!d.getTransactionStatus().equals(TradeStatus.ONGOING.getCode())) {
                return StatusCode.OPERATION_FAILED.getMsg();
            }
            Date now = new Date();
            UserTransactionRecordPO recordDetail = recordRepository.getRecordDetail(recordId);
            recordDetail.setTransactionStatus(TradeStatus.SUCCESS.getCode());
            recordDetail.setUpdateTime(now);
            recordRepository.updateRecord(recordDetail);
            BigDecimal balance = walletRepository.doGetBalance(recordDetail.getAccountUserId()).getBalance();
            BigDecimal newBalance = balance.add(recordDetail.getTransactionAmount());
            UserWalletPO po = new UserWalletPO();
            po.setUserId(recordDetail.getAccountUserId());
            po.setBalance(newBalance);
            po.setUpdateTime(now);
            walletRepository.updateBalance(po);
            // 完成
            return "支付完成，商家将尽快发货";
        } else {
            return "支付失败，请返回订单页查看订单状态，或重新支付！";
        }
    }

    // 接收处理支付宝的跳转（支付完成后自动重定向到此处）
    @ApiIgnore
    @GetMapping("/finish")
    public String finish() {
        return "支付完成，请返回订单页查看订单状态！";
    }
}
